﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Web;
using System.Web.Security;
using System.Data;
using System.Data.SqlClient;
using ProjectGroep3.ws_Groep3;
using System.Collections;
using MahApps.Metro.Controls;
using ClassLibrary;
using System.Windows.Markup;
using System.Xaml;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using MahApps.Metro.Controls.Dialogs;
using System.ComponentModel;





namespace ProjectGroep3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class AdminWindow : MetroWindow, INotifyPropertyChanged
    {
        DataTable dt, dtEvent, dtCompanies, dtConForms = new DataTable();
        private WebService ws = new WebService();
        private metroMessageDialog mmd = new metroMessageDialog();
        private int cId, coNum;
        private bool confirmation= false;
        private string price, formulId, end;




        //constructors, methodes
        #region
        // default constructor
        public AdminWindow()
        {
            DataContext = this;
            InitializeComponent();
            getUsers();
            getCompany();
            getContracts();
            getReservations();
            getEvents();
        }
        // Genereert de Admintabel op het Userstab
        private void getAdmins()
        {
            var list = Roles.GetUsersInRole("Administrators").Select(Membership.GetUser).ToList();
            dtgUsers.ItemsSource = list;
        }
        // Genereert de UserTabel op het usertab
        private void getUsers()
        {
            var list = Roles.GetUsersInRole("Users").Select(Membership.GetUser).ToList();
            dtgUsers.ItemsSource = list;
        }
        // Verwijdert de geselecteerde user(controle + bevestiging)
        private async void removeUser()
        {
            try
            {
                if (dtgUsers.SelectedIndex != -1)
                {
                    IList list = dtgUsers.SelectedItems;
                    string user = list[0].ToString();
                    await generateConfirmation(this, "Are you sure you want to delete " + user + " ?");


                    if (confirmation == true)
                    {
                        mmd.generateDialog(this, "Succes", user + " removed.");
                        Membership.DeleteUser(user);
                        getUsers();
                    }
                }
                else mmd.generateDialog(this, "Error", "No user selected.");
            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }
        // Promoveert de User tot een gebruiker
        private void promoteUser()
        {
            if (dtgUsers.SelectedIndex != -1)
            {
                IList list = dtgUsers.SelectedItems;
                string user = list[0].ToString();
                Roles.RemoveUserFromRole(user, "Users");
                Roles.AddUserToRole(user, "Administrators");
                getUsers();
            }
            else mmd.generateDialog(this, "Error", "No user selected.");
        }
        // Genereert de Company tabel
        private void getCompany()
        {
            dt = ws.getCompany().Tables[0];
            dtgCompany.ItemsSource = dt.DefaultView;
        }
        // laad de bedrijven  
        private int loadCompany()
        {
            if (dtgCompany.SelectedIndex != -1)
            {

                DataRowView drv = (DataRowView)dtgCompany.SelectedItem;
                int id = Convert.ToInt32(drv[0]);

                string name = drv[1].ToString();
                txtCName.Text = name;

                string street = drv[2].ToString();
                txtCStreet.Text = street;

                string zip = drv[3].ToString();
                txtCZip.Text = zip;

                string city = drv[4].ToString();
                txtCCity.Text = city;

                string country = drv[5].ToString();
                txtCCountry.Text = country;

                string email = drv[6].ToString();
                txtCEmail.Text = email;

                string phone = drv[7].ToString();
                txtCPhone.Text = phone;

                string employees = drv[8].ToString();
                txtCEmployees.Text = employees;
                companyFlyout.IsOpen = true;

                companyFlyout.Header = "Update Company";
                btnFlyoutUpdate.Visibility = Visibility.Visible;
                btnFlyoutCreate.Visibility = Visibility.Hidden;

                return id;

            }
            else mmd.generateDialog(this, "Error", "No Company selected.");
            return 0;

        }
        // Update de bedrijven
        private void updateCompany(int id)
        {

            try
            {

                string err = isEmpty(txtCEmail.Text);
                if (err.Equals(""))
                {
                    companyFlyout.Header = "Add Company";
                    string name = txtCName.Text;
                    string street = txtCStreet.Text;
                    int zip = Convert.ToInt32(txtCZip.Text);
                    string city = txtCCity.Text;
                    string country = txtCCountry.Text;
                    string email = txtCEmail.Text;
                    int phone = Convert.ToInt32(txtCPhone.Text);
                    string employees = txtCEmployees.Text;

                    if (ws.updateCompany(id, name, street, zip, city, country, email, phone, employees) == true)
                    {
                        mmd.generateDialog(this, "Succes", name + " was adjusted.");
                        getCompany();
                        companyFlyout.IsOpen = false;

                    }
                }
                else
                    mmd.generateDialog(this, "Error", err);
            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }


        }
        // Verwijdert het geselecteerde bedrijf(controle + bevestiging) 
        private async void removeCompany()
        {
            try
            {
                if (dtgCompany.SelectedIndex != -1)
                {

                    DataRowView drv = (DataRowView)dtgCompany.SelectedItem;
                    int companyId = Convert.ToInt32(drv[0]);
                    string companyNaam = drv[1].ToString();
                    await generateConfirmation(this, "Are you sure you want to delete?");
                 


                    if (confirmation==true)
                    {
                        mmd.generateDialog(this, "Succes", companyNaam + " removed.");
                        ws.removeCompany(companyId);
                        getCompany();
                    }
                }
                else mmd.generateDialog(this, "Error", "No Company selected.");

            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }
        //Contracten laden
        private int loadContract()
        {
            if (dtgContracts.SelectedIndex != -1)
            {
                clearContractFields();
                companyFlyout.Header = "Update Contract";

                DataRowView drv = (DataRowView)dtgContracts.SelectedItem;

                int id = Convert.ToInt32(drv[0]);

                DateTime start;
                if (DateTime.TryParse(drv["STARTDATE"].ToString(), out start))
                    dtpConStartDate.SelectedDate = start.Date;

                DateTime end;
                if (DateTime.TryParse(drv["ENDDATE"].ToString(), out end))
                    dtpConEndDate.SelectedDate = end.Date;

                int compId = Convert.ToInt32(drv["COMPANYID"]);
                foreach (ComboBoxItem item in cmbCompany.Items)
                {
                    if(Convert.ToInt32(item.Tag) == compId)
                    {
                         cmbCompany.SelectedItem = item;
                    }
                }

                int conformId = Convert.ToInt32(drv["ContractFomulaId"]);
                foreach (ComboBoxItem item in cmbConForm.Items)
                {
                    if (Convert.ToInt32(item.Tag) == conformId)
                    {
                        cmbConForm.SelectedItem = item;
                    }
                }
                contractFlyout.IsOpen = true;
                contractFlyout.Header = "Update Contract";
                return id;
            }
            else mmd.generateDialog(this, "Error", "No Contract selected.");
            return 0;
        }
        //Contracten aanmaken
        private void createContract()
        {
            try
            {
                string err = isNotFilled(dtpConStartDate.Text);
                if (err.Equals(""))
                {
                    DateTime startDate = dtpConStartDate.SelectedDate.Value.Date;
                    int conCompId = Convert.ToInt32(((ComboBoxItem)this.cmbCompany.SelectedItem).Tag);
                    int conFormId = Convert.ToInt32(((ComboBoxItem)this.cmbConForm.SelectedItem).Tag);
                    DateTime endDate = dtpConEndDate.SelectedDate.Value.Date; ;
                    dtpConEndDate.SelectedDate = dtpConStartDate.SelectedDate.Value.AddMonths(1);

                    if (ws.registerContract(startDate, endDate, conCompId, conFormId, 0) == true)
                    {
                        mmd.generateDialog(this, "Succes", "Contract for " + startDate + " was added.");
                        contractFlyout.IsOpen = false;
                        getContracts();
                    }
                }
                else
                    mmd.generateDialog(this, "Error", err);
            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }
        //Contracten wijzigen
        private void updateContract(int id)
        {
            try
            {
                string err = isNotFilled(dtpConStartDate.Text);
                if (err.Equals(""))
                {
                    contractFlyout.Header = "Update Contract";

                    DateTime startDate = dtpConStartDate.SelectedDate.Value.Date;
                    DateTime endDate = dtpConEndDate.SelectedDate.Value.Date;
                    int conCompId = Convert.ToInt32(((ComboBoxItem)this.cmbCompany.SelectedItem).Tag);
                    int conFormId = Convert.ToInt32(((ComboBoxItem)this.cmbConForm.SelectedItem).Tag);

                    if (ws.updateContract(id, startDate, endDate.Date, conCompId, conFormId) == true)
                    {
                        mmd.generateDialog(this, "Succes", "Contract for " + startDate + " was adjusted.");
                        contractFlyout.IsOpen = false;
                        getContracts();
                    }
                }
                else
                    mmd.generateDialog(this, "Error", err);
            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }


        }
        // Contract verwijderen
        private async void removeContract()
        {
            try
            {
                if (dtgContracts.SelectedIndex != -1)
                {
                    DataRowView drv = (DataRowView)dtgContracts.SelectedItem;

                    String companyName = (drv["Name"]).ToString();
                    int contractNumber = Convert.ToInt32(drv["Number"]);
                    await generateConfirmation(this, "Are you sure you want to delete the contract of " + companyName + " ?");

  

                    if (confirmation == true)
                    {
                        mmd.generateDialog(this, "Succes", contractNumber + " removed.");
                        ws.deleteContract(contractNumber);
                        getContracts();
                    }
                }
                else mmd.generateDialog(this, "Error", "No contract selected.");
            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }

        // Vult Contracten grid met alle contracten
        private void getContracts()
        {
            dt = ws.getAllContract().Tables[0];
            dtgContracts.ItemsSource = dt.DefaultView;
        }
        private async void removeReservation()
        {
            try
            {
                if (dtgReservations.SelectedIndex != -1)
                {

                    DataRowView drv = (DataRowView)dtgReservations.SelectedItem;
                    int reservationId = Convert.ToInt32(drv[0]);
                    string reservationDate = drv[1].ToString();
                    await generateConfirmation(this, "Are you sure you want to delete?");

             

                    if (confirmation == true)
                    {
                        mmd.generateDialog(this, "Succes", reservationDate + " removed.");
                        ws.deleteReservation(reservationId);
                        getReservations();
                    }
                }
                else mmd.generateDialog(this, "Error", "No reservation selected.");

            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }
        //maakt alle velden eerst leeg bij het aanmaken van contract
        private void clearContractFields()
        {
            dtpConStartDate.Text = "";
            cmbCompany.SelectedIndex = -1;
            cmbConForm.SelectedIndex = -1;
            dtpConEndDate.Text = "";
        }
        // Controle of alle velden leeg zijn bij contract
        private string isNotFilled(string number)
        {
            string err = "";
            int val;

            if (dtpConStartDate.Text.Trim().Length == 0) err += "Stardate is empty\n";
            if (dtpConEndDate.Text.Trim().Length == 0) err += "Enddate is empty\n";
            if (cmbCompany.SelectedIndex == -1)
            {
                err = err + "No company selected\n";
            }

            if (cmbConForm.SelectedIndex == -1)
            {
                err += "ContractFrormulaId is empty\n";
            }

            
            return err;
        }
        // email validator
        public bool IsValidEmail(string str)
        {
            return Regex.IsMatch(str, @"^[\w!#$%&'*+\-/=?\^_`{|}~]+(\.[\w!#$%&'*+\-/=?\^_`{|}~]+)*" + "@" + @"((([\-\w]+\.)+[a-zA-Z]{2,4})|(([0-9]{1,3}\.){3}[0-9]{1,3}))$");
        }
        // Maakt een nieuw bedrijf aan
        private void createCompany()
        {
            try
            {
                string err = isEmpty(txtCEmail.Text);
                if (err.Equals(""))
                {
                    string name = txtCName.Text;
                    string street = txtCStreet.Text;
                    int zip = Convert.ToInt32(txtCZip.Text);
                    string city = txtCCity.Text;
                    string country = txtCCountry.Text;
                    string email = txtCEmail.Text;
                    int phone = Convert.ToInt32(txtCPhone.Text);
                    string employees = txtCEmployees.Text;
                    if (ws.registerCompany(name, street, zip, city, country, email, phone, employees) == true)
                    {
                        mmd.generateDialog(this, "Succes", name + " was added.");
                        getCompany();
                        companyFlyout.IsOpen = false;
                    }

                }
                else
                    mmd.generateDialog(this, "Error", err);


            }
            catch (Exception ex)
            {
                Logging.Log(ex.Message + ex.StackTrace);
                mmd.generateDialog(this, "Error", "More details in the logging file.");
            }
        }
        // Vult Contracten grid met alle contracten
        private void getReservations()
        {
            dt = ws.getAllReservations().Tables[0];
            dtgReservations.ItemsSource = dt.DefaultView;
        }

        private void getEvents()
        {
            try
            {
                dtEvent = ws.getAllEvents().Tables[0];
                foreach (DataRow row in dtEvent.Rows)
                {
                    object value = row["ContractId"];
                    //kijken of reservatie is aangepast en contractId dus leeg is
                    if (value == DBNull.Value)
                    {
                        //kijken of het event 0 is en dus een delete
                        if (Convert.ToInt32(row["Event"]) == 0)
                        {
                            TxtEventsBlock.Inlines.Add("On " + row["EventTime"] + " " + row["UserName"] + " has cancelled the booking of " + row["Room"] + " for " + row["BookTime"] + "\n");
                        }
                        //anders is het 1 en dus een creatie
                        else
                        {
                            TxtEventsBlock.Inlines.Add("On " + row["EventTime"] + " " + row["UserName"] + " has booked " + row["Room"] + " for " + row["BookTime"] + "\n");
                        }
                    } 
                    //geen reservatie dus contract
                    else
                    {
                        TxtEventsBlock.Inlines.Add("On " + row["EventTime"] + " " + row["UserName"] + " has cancelled the contract of " + row["company"] + "\n");
                    }
                }

            }
            catch (Exception)
            {

                throw;
            }
        }
        // maakt alle velden eerst leeg bij het aanmaken van company
        private void clearFields()
        {
            txtCName.Text = "";
            txtCCity.Text = "";
            txtCCountry.Text = "";
            txtCEmail.Text = "";
            txtCEmployees.Text = "";
            txtCPhone.Text = "";
            txtCStreet.Text = "";
            txtCZip.Text = "";
        }
        // Controle of alle velden leeg zijn 
        private string isEmpty(string email)
        {
            string err = "";
            int val;

            if (txtCName.Text.Trim().Length == 0) err += "NameField is empty\n";
            if (txtCStreet.Text.Trim().Length == 0) err += "StreetField is empty\n";
            if (txtCZip.Text.Trim().Length == 0)
            {
                err = err + "ZipcodeFIeld is empty\n";
            }
            else if (Int32.TryParse(txtCZip.Text, out val) == false)
            {
                err += "Zipcode is not a number\n";
            }
            if (txtCCity.Text.Trim().Length == 0) err += "CityField is empty\n";
            if (txtCCountry.Text.Trim().Length == 0) err += "CountryField is empty\n";
            if (txtCPhone.Text.Trim().Length == 0)
            {
                err += "PhoneField is empty\n";
            }
            else if (Int32.TryParse(txtCPhone.Text, out val) == false)
            {
                err += "PhoneField is not a number\n";
            }
            if (txtCEmail.Text.Trim().Length == 0)
            {
                err += "EmailField is empty\n";
            }
            else if (IsValidEmail(email) == false)
            {
                err += "Not a valid email\n";
            }
            if (txtCEmployees.Text.Trim().Length == 0) err += "EmployeesField is empty\n";

            return err;

        }

        //Databinding van velden stardate en price bij creatie van nieuwe contracten 
       

        public string formulaId
        {
            get { return formulId; }
            set
            {
                formulId = value;
                updateCells();
            }
        }

        public string endDate
        {
            get { return end; }
            set
            {
                end = value;

                OnNotifyPropertyChanged("EndDate");
            }
        }

        public string Price
        {
            get { return price; }
            set
            {
                price = value;

                OnNotifyPropertyChanged("Price");
            }
        }


        private void OnNotifyPropertyChanged(string p)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }

        public void updateCells()
        {


            if (dtpConStartDate.Text.Trim().Length != 0)
            {
                endDate = (dtpConStartDate.SelectedDate.Value.AddMonths(1).ToShortDateString());

                string fId = (formulId);
                switch (fId)
                {
                    case "1":
                        price = "100";
                        end = dtpConStartDate.SelectedDate.Value.Date.AddMonths(1).ToString();
                        break;
                    case "2":
                        price = "200";
                        end = dtpConStartDate.SelectedDate.Value.Date.AddMonths(1).ToString();
                        break;
                    case "3":
                        price = "500";
                        end = dtpConStartDate.SelectedDate.Value.Date.AddMonths(1).ToString();
                        break;
                    case "4":
                        price = "500";
                        end = dtpConStartDate.SelectedDate.Value.Date.AddMonths(2).ToString();
                        break;
                    case "5":
                        price = "1200";
                        end = dtpConStartDate.SelectedDate.Value.Date.AddMonths(6).ToString();
                        break;
                    default:
                        price = "";
                        end = "";
                        break;
                }
            }

        }
        #endregion

        //Interactie met interface
        #region
        private void btnRemoveUser_Click(object sender, RoutedEventArgs e)
        {
            removeUser();
        }

        private void btnUsers_Click(object sender, RoutedEventArgs e)
        {
            getUsers();
            btnRemoveUser.Visibility = Visibility.Visible;
            btnMakeAdmin.Visibility = Visibility.Visible;
        }

        private void btnAdmins_Click(object sender, RoutedEventArgs e)
        {
            getAdmins();
            btnRemoveUser.Visibility = Visibility.Hidden;
            btnMakeAdmin.Visibility = Visibility.Hidden;
        }

        private void btnMakeAdmin_Click(object sender, RoutedEventArgs e)
        {
            promoteUser();
        }

        private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Login login = new Login();
            login.Show();
            this.Close();
        }

        private void btnRemoveCompany_Click(object sender, RoutedEventArgs e)
        {
            companyFlyout.IsOpen = false;
            removeCompany();

        }

        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {
            cId = loadCompany();
            contractFlyout.IsOpen = false;
        }

        private void btnFlyoutUpdate_Click(object sender, RoutedEventArgs e)
        {
            updateCompany(cId);
            



        }

        private void btnCreate_Click(object sender, RoutedEventArgs e)
        {
            companyFlyout.Header = "Create Company";
            btnFlyoutCreate.Visibility = Visibility.Visible;
            btnFlyoutUpdate.Visibility = Visibility.Hidden;
            clearFields();
            companyFlyout.IsOpen = true;
            contractFlyout.IsOpen = false;
        }

        private void btnFlyoutCreate_Click(object sender, RoutedEventArgs e)
        {

            createCompany();

        }

        private void btnRemoveReservation_Click(object sender, RoutedEventArgs e)
        {
            removeReservation();
        }

        private void btnRemoveContract_Click(object sender, RoutedEventArgs e)
        {
            contractFlyout.IsOpen = false;
            removeContract();
        }

        private void btnUpdateContract_Click(object sender, RoutedEventArgs e)
        {
            fillCboCompanies();
            fillCmbConForm();
            coNum = loadContract();
            btnFlyoutUpdateContract.Visibility = Visibility.Visible;
            btnFlyoutCreateContract.Visibility = Visibility.Hidden;
            companyFlyout.IsOpen = false;
        }

        private void btnCreateContract_Click(object sender, RoutedEventArgs e)
        {
            fillCboCompanies();
            fillCmbConForm();
            contractFlyout.Header = "Create Contract";
            btnFlyoutCreateContract.Visibility = Visibility.Visible;
            btnFlyoutUpdateContract.Visibility = Visibility.Hidden;
            clearContractFields();
            contractFlyout.IsOpen = true;
            companyFlyout.IsOpen = false;
        }
        private void btnFlyoutCreateContract_Click(object sender, RoutedEventArgs e)
        {
            createContract();
        }
      
        private void btnFlyoutUpdateContract_Click(object sender, RoutedEventArgs e)
        {
            updateContract(coNum);
        }
        public async Task generateConfirmation(MetroWindow handle, string message)
        {
            MessageDialogResult result = await handle.ShowMessageAsync(message, "", MessageDialogStyle.AffirmativeAndNegative);
            if (result == MessageDialogResult.Affirmative)
            {
                confirmation = true;

            }
            else
            {
                confirmation = false;
            }




        }

        public void fillCboCompanies()
        {
            cmbCompany.Items.Clear();
            dtCompanies = ws.getCompany().Tables[0];
            foreach (DataRow row in dtCompanies.Rows)
            {
                ComboBoxItem comboFill = new ComboBoxItem();
                comboFill.Content = row["Name"].ToString();
                comboFill.Tag = row["Id"].ToString();
                cmbCompany.Items.Add(comboFill);
            }
        }

        public void fillCmbConForm()
        {
            cmbConForm.Items.Clear();
            dtConForms = ws.getContractFormulas().Tables[0];
            foreach (DataRow row in dtConForms.Rows)
            {
                ComboBoxItem comFill = new ComboBoxItem();
                comFill.Content = row["Description"].ToString();
                comFill.Tag = row["Id"].ToString();
                cmbConForm.Items.Add(comFill);
            }
        }



        public event PropertyChangedEventHandler PropertyChanged;
    }
        #endregion


}

